package com.atguigu.cart.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.atguigu.cart.contant.CartContant;
import com.atguigu.cart.feign.ProductFeign;
import com.atguigu.cart.interceptor.CartInterceptor;
import com.atguigu.cart.service.CartService;
import com.atguigu.cart.to.UserInfoTo;
import com.atguigu.cart.vo.Cart;
import com.atguigu.cart.vo.CartItem;
import com.atguigu.cart.vo.PmsSkuInfoVo;
import com.atguigu.common.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private ThreadPoolExecutor executor;


    @Autowired
    private ProductFeign productFeign;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 添加商品到购物车
     *
     * @param skuId
     * @param num
     * @return
     */
    public CartItem addToCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {
        //封装对象返回
        CartItem item = new CartItem();
        CompletableFuture<Void> skuInfo = CompletableFuture.runAsync(() -> {
            //1.根据商品id查询商品详情
            R info = productFeign.info(skuId);
            PmsSkuInfoVo pmsSkuInfo = info.getData("pmsSkuInfo", new TypeReference<PmsSkuInfoVo>() {
            });
            item.setCheck(true);
            item.setCount(num);
            item.setImage(pmsSkuInfo.getSkuDefaultImg());
            item.setPrice(pmsSkuInfo.getPrice());
            item.setSkuId(skuId);
            item.setTitle(pmsSkuInfo.getSkuTitle());
        }, executor);


        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
            //根据商品id查询商品销售属性
            R r = productFeign.cartSkuId(skuId);
            if (r.getCode() == 0) {
                List<String> saleAttrValue = r.getData("pmsSkuSaleAttrValue", new TypeReference<List<String>>() {
                });
                item.setSkuAttr(saleAttrValue);
            }
        }, executor);

        CompletableFuture.allOf(skuInfo, completableFuture).get();
        //执行方法之后存入redis
        //生成购物车
        BoundHashOperations boundHashOperations = createCart();

        //存入redis需要判断是否该商品已经存在于redis中
        CartItem cartItem = (CartItem) boundHashOperations.get(skuId.toString());
        if (cartItem != null) {
            //说明之前已经存入过
            item.setCount(cartItem.getCount() + num);
            boundHashOperations.put(skuId.toString(), item);

        } else {
            boundHashOperations.put(skuId.toString(), item);
        }


        return item;
    }

    /**
     * 根据商品id查询对应的商品信息
     *
     * @param skuId
     * @return
     */
    public CartItem addToCartSuccess(Long skuId) {
        BoundHashOperations boundHashOperations = createCart();
        CartItem cartItem = (CartItem) boundHashOperations.get(skuId.toString());
        return cartItem;
    }

    /**
     * 查询用户的购物车--以及需要将未登录的购物车数据整合到登录的购物车
     *
     * @return
     */
    public Cart cartList() throws ExecutionException, InterruptedException {
        Cart cart = new Cart();
        //判断用户是否登录
        UserInfoTo userInfoTo = CartInterceptor.local.get();
        //获取用户的购物车
        BoundHashOperations boundHashOperations = createCart();
        if (userInfoTo.getUserId() == null) {
            List<CartItem> items = boundHashOperations.values();
            cart.setItems(items);
        } else {
            //整合购物车操作
            //获取未登录的购物车信息
            BoundHashOperations boundHashOps = redisTemplate.boundHashOps(CartContant.CART_KEY_CREATE_PRE + userInfoTo.getUserKey());
            List<CartItem> cartItems = boundHashOps.values();
            if (cartItems != null && cartItems.size() > 0) {
                for (CartItem cartItem : cartItems) {
                    //在登录的购物车中添加商品和数量等信息
                    addToCart(cartItem.getSkuId(), cartItem.getCount());
                }
            }
            //查询登录购物车的数据
            List<CartItem> itemList = boundHashOperations.values();
            cart.setItems(itemList);

            //删除临时购物车的数据
            redisTemplate.delete(CartContant.CART_KEY_CREATE_PRE + userInfoTo.getUserKey());


        }
        return cart;
    }

    /**
     * 改变购物车某一商品数量
     *
     * @param skuId
     * @param num
     */
    public void countItem(Long skuId, Integer num) {
        //获取该条数据信息
        CartItem cartItem = addToCartSuccess(skuId);
        cartItem.setCount(num);
        updateNum(skuId, cartItem);
    }

    /**
     * 改变购物车某一商品状态
     *
     * @param skuId
     * @param num
     */
    public void checkItem(Long skuId, Integer check) {
        //获取该条数据信息
        CartItem cartItem = addToCartSuccess(skuId);
        cartItem.setCheck(check == 1 ? true : false);
        updateNum(skuId, cartItem);
    }

    /**
     * 删除对应的商品信息
     *
     * @param skuId
     */
    public void deleteItem(Long skuId) {
        BoundHashOperations cart = createCart();
        cart.delete(skuId.toString());

    }

    @Override
    public List<CartItem> orderToCart() {
        BoundHashOperations boundHashOperations = createCart();
        //获取购物车中的所有数据
        List<CartItem> items = boundHashOperations.values();

        List<CartItem> cartItems = items.stream().filter((m) -> m.getCheck())
                .map((m)->{
                   //远程调用商品模块查看商品最新价格
                    R info = productFeign.info(m.getSkuId());
                    PmsSkuInfoVo pmsSkuInfo = info.getData("pmsSkuInfo", new TypeReference<PmsSkuInfoVo>() {
                    });
                    m.setPrice(pmsSkuInfo.getPrice());
                    return m;
                }).collect(Collectors.toList());
        return cartItems;
    }

    //定义方法创建购物车
    public BoundHashOperations createCart() {

        //获取用户对象判断是否登录
        String key = "";
        UserInfoTo userInfoTo = CartInterceptor.local.get();
        if (userInfoTo.getUserId() == null) {
            key = CartContant.CART_KEY_CREATE_PRE + userInfoTo.getUserKey();
        } else {
            key = CartContant.CART_KEY_CREATE_PRE + userInfoTo.getUserId();
        }


        //生成对应的购物车
        BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(key);

        return boundHashOperations;
    }


    /**
     * 根据商品id修改对应的属性--默认在购物车存在此商品
     *
     * @param skuId
     * @return
     */
    public void updateNum(Long skuId, CartItem item) {
        BoundHashOperations boundHashOperations = createCart();
        boundHashOperations.put(skuId.toString(), item);
    }
}
